"""
1. user_id：用户在系统中的唯一身份标识
2. register_time：用户账号的首次创建时间
3. gender：用户自填或系统推断的性别
4. avg_watch_minutes：用户"平均每日观看视频的总时长"（单位：分钟）
5. total_watch_count：用户累计观看视频的"总次数"
6. favorite_tags：用户"喜欢/偏好"的视频标签列表
"""
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import random
import json

# 设置随机种子以便复现
np.random.seed(42)
random.seed(42)

class EnhancedUserGenerator:
    def __init__(self, num_users=1000, start_date='2020-01-01', end_date=None):
        self.num_users = num_users
        self.start_date = datetime.strptime(start_date, '%Y-%m-%d')
        if end_date is None:
            # 默认使用当前时间作为结束日期
            self.end_date = datetime.now()
        else:
            self.end_date = datetime.strptime(end_date, '%Y-%m-%d')
        
        # 与视频标签池保持一致的标签池
        self.tag_pool = [
            # 搞笑娱乐类标签
            '搞笑', '沙雕', '段子', '神回复', '神评论', '翻车现场', '恶搞', '社死', '尴尬', '神操作',
            '搞笑合集', '沙雕日常', '经典段子', '神回复现场', '恶搞系列', '沙雕挑战', '搞笑配音',
            '段子合集', '神评论大赏', '翻车合集', '恶搞实验', '沙雕网友', '段子手合集',
            '恶搞挑战', '搞笑日常', '沙雕操作', '神评论合集', '恶搞配音', '沙雕实验',
            '搞笑萌宠', '社死现场', '尴尬瞬间',
            
            # 游戏电竞类标签
            '游戏', '电竞', '主播', '直播', '开黑', '上分', '排位', '段位', '王者', '吃鸡',
            'LOL', '王者荣耀', '和平精英', '原神', '崩坏', '明日方舟', '阴阳师',
            'FPS', 'MOBA', '休闲小游戏', '游戏解说', '游戏攻略', '游戏翻车', '游戏技巧',
            '操作', '技巧', '攻略', '教学', '解说', '复盘', '分析', '战术', '策略',
            '装备', '技能', '天赋', '符文', '出装', '铭文', '皮肤', '英雄', '角色',
            '团战', '单杀', '双杀', '三杀', '四杀', '五杀', '超神', '连杀', 'MVP',
            '翻盘', '逆风', '顺风', '碾压', '虐菜', '代练', '上分', '掉分', '坑货',
            '队友', '对手', '敌人', '野怪', '小兵', '塔', '水晶', '基地', '泉水',
            
            # 影视综艺类标签
            '影视', '剧情', '角色', '演员', '特效', '音乐', '画面', '结局', '反转', '彩蛋', '细节',
            '影视推荐', '影视吐槽', '剧情解说', '剧情反转', '爽剧推荐', '爽剧解说',
            '综艺名场面', '韩剧解说', '美剧推荐', '国产剧推荐', '经典港片', '电影解说',
            '电视剧推荐', '综艺推荐', '真人秀', '霸总', '甜宠', '悬疑', '穿越', '高燃混剪', 'CP混剪', '名场面',
            
            # 颜值穿搭类标签
            '颜值', '穿搭', 'OOTD', '写真', '宅舞', 'JK制服', '汉服', 'cos', '舞室练习', '气质',
            '美女写真', '帅哥写真', '穿搭打卡', '擦边舞蹈', 'cosplay', '气质美女',
            '健身型男', '妆造教程', '穿搭分享', '时尚潮流', '美妆教程', '护肤分享',
            '美女', '帅哥', '身材', '大长腿', '小蛮腰', '马甲线', '腹肌', '胸肌', '翘臀', '美腿',
            '锁骨', '天鹅颈', '蜜桃臀', '比基尼', '泳装', '内衣', '丝袜', '高跟鞋', '短裙', '热裤', '露脐装',
            '湿身', '出水芙蓉', '撩人', '勾魂', '魅惑', '风情万种',
            
            # 萌宠治愈类标签
            '萌宠', '萌娃', '猫咪', '狗狗', '仓鼠', '兔子', '小鸟', '金鱼', '乌龟', '龙猫', '刺猬',
            '萌宠日常', '搞笑萌宠', '治愈萌宠', '萌宠搞笑', '猫咪日常', '狗狗日常',
            '仓鼠日常', '异宠日常', '萌宠合集', '治愈系', '可爱', '治愈', '解压', '泪目', '高燃', '全程姨母笑',
            
            # 美食探店类标签
            '美食', '料理', '烹饪', '下厨', '厨房', '菜谱', '教程', '步骤', '做法',
            '探店', '打卡', '种草', '拔草', '推荐', '避雷', '踩雷', '翻车',
            '美食探店', '奇葩美食', '美食制作', '美食挑战', '街头美食', '网红美食',
            '地方特色', '美食测评', '美食教程', '美食分享',
            '蛋糕', '面条', '饺子', '包子', '汤圆', '月饼', '火锅', '烧烤', '甜品', '家常菜',
            
            # 音乐舞蹈类标签
            '音乐', '翻唱', '洗脑神曲', '舞蹈挑战', '手势舞', '音乐分享', '原创音乐',
            '音乐制作', '乐器演奏', '音乐教学', '舞蹈教学', '音乐现场',
            '歌曲', '舞蹈', '洗脑', '治愈', '节奏', '旋律', '表演', '挑战',
            
            # 生活实用类标签
            '生活', '技巧', '实用技巧', '职场', '理财', '健康', '养生', '家庭', '教育', '心理', '法律',
            '生活小技巧', '职场干货', '情感故事', '职场技能', '理财知识', '健康养生',
            '家庭教育', '心理知识', '法律知识', '减肥', '瘦身', '健身', '运动', '瑜伽', '跑步', '游泳', '骑行',
            '护肤', '化妆', '美妆', '时尚', '潮流', '搭配', '风格',
            
            # 知识科普类标签
            '科技', '知识', '科普', '科学', '实验', '历史', '文化', '地理', '生物', '物理', '化学',
            '知识科普', '科技前沿', '科学实验', '历史趣闻', '文化知识', '地理知识',
            '生物知识', '物理知识', '化学知识', '技术', '发明', '创新', '原理', '应用', '未来', '智能', '数字',
            
            # 旅行户外类标签
            '旅行', 'vlog', '户外', '探险', '自驾', '背包', '城市', '自然', '风光', '人文', '景观',
            '旅行vlog', '户外探险', '自驾游', '背包客', '城市探索', '自然风光',
            '人文景观', '旅行攻略', '旅行分享', '户外运动',
            
            # 健身运动类标签
            '健身', '运动', '瑜伽', '跑步', '游泳', '骑行', '减肥', '塑形', '挑战', '日常',
            '健身打卡', '健身教程', '运动技巧', '减肥分享', '塑形教程', '运动挑战', '健身日常',
            
            # 教育学习类标签
            '教育', '学习', '考试', '考研', '英语', '编程', '技能', '语言', '方法', '技巧', '分享',
            '英语学习', '编程教学', '技能学习', '语言学习', '学习方法', '学习技巧', '考试技巧', '学习分享',
            
            # 热点时事类标签
            '热点', '热搜', '爆款', '刷屏', '刷爆', '火遍全网', '全网热议', '明星', '网红', '博主',
            '大V', 'KOL', '意见领袖', '流量', '粉丝', '八卦', '爆料', '内幕', '真相', '反转', '打脸',
            '真香', '真香定律', '热点追踪', '今日热点', '时事评论', '社会热点', '新闻解读', '热点分析',
            '明星八卦', '网红资讯', '社会新闻', '国际新闻', '财经新闻', '科技新闻',
            
            # 情感心理类标签
            '情感', '恋爱', '单身', '脱单', '分手', '复合', '前任', '现任', '暗恋', '表白', '被表白',
            '拒绝', '接受', '异地恋', '网恋', '相亲', '催婚', '结婚', '离婚', '出轨', '小三',
            '渣男', '渣女', '绿茶', '白莲花', '父母', '子女', '婆媳', '夫妻', '情侣',
            '朋友', '闺蜜', '兄弟', '情感故事', '心理分析', '情感咨询', '恋爱技巧', '婚姻生活',
            '家庭关系', '心理健康', '情感治愈', '心理测试', '情感分享', '心理知识', '情感建议',
            
            # 手工创意类标签
            '手工', 'DIY', '创意', '设计', '艺术', '创作', '工艺品', '绘画', '书法', '摄影', '剪辑',
            '手工制作', '创意DIY', '手工教程', '创意设计', '艺术创作', '手工艺品',
            '绘画教程', '书法教学', '摄影技巧', '视频剪辑', '创意视频', '艺术分享',
            
            # 汽车科技类标签
            '汽车', '评测', '知识', '改装', '驾驶', '保养', '新车', '科技', '产品', '数码', '手机', '电脑',
            '汽车评测', '汽车知识', '汽车改装', '驾驶技巧', '汽车保养', '新车推荐',
            '科技产品', '数码评测', '手机测评', '电脑配置', '科技资讯', '数码科技',
            
            # 母婴育儿类标签
            '母婴', '育儿', '儿童', '教育', '亲子', '互动', '用品', '技巧', '心理', '家庭', '游戏', '健康',
            '母婴知识', '育儿经验', '儿童教育', '亲子互动', '母婴用品', '育儿技巧',
            '儿童心理', '家庭教育', '亲子游戏', '儿童健康', '育儿分享', '母婴护理',
            
            # 二次元动漫类标签
            '二次元', '动漫', '番剧', '新番', '完结', '追番', '补番', '推荐', '安利',
            '手办', '周边', '同人', '本子', '图包', '壁纸', '头像', '表情包',
            '声优', 'CV', '配音', '主题曲', 'OP', 'ED', 'BGM', '插曲',
            '人设', '画风', '制作', '经费', '崩坏', '作画', '分镜', '手书', 'AMV', 'MAD',
            
            # 其他热门标签
            '短视频', '竖屏剧场', '一口气看完', '3分钟系列', '挑战', '合拍', 'duet', 'react', '投票',
            '今日热点', '520', '毕业季', '世界杯', '跨年', '春节档', '上热门', '宝藏博主', '关注我',
            '广告', '植入', '联名', '开箱测评', '直播带货', '宿舍日常', '打工日记', '老板来了',
            '闺蜜', '男友视角', '熊孩子', '高能时刻', '搞笑击杀', '沙雕MOD', '彩蛋', '奇葩美食', '街头实验'
        ]
        
        # 用户类型定义
        # 根据视频类型偏好重新定义用户类型
        self.user_types = {
            'short_video_user': {
                'weight': 0.40,  # 40%短视频偏好用户
                'description': '偏好短视频（<2分钟），观看次数多，时长短',
                'daily_watch_time': (15, 60),  # 分钟 - 短视频用户观看时间相对较短
                'avg_video_duration_preference': '< 2分钟',  # 偏好视频时长
                'watch_count_multiplier': 1.5,  # 观看次数倍数（相对于平均水平）
                'interaction_rates': {
                    'like_rate': (0.06, 0.12),
                    'comment_rate': (0.015, 0.04),
                    'favorite_rate': (0.02, 0.06),
                    'repost_rate': (0.005, 0.02)
                }
            },
            'mixed_user': {
                'weight': 0.45,  # 45%混合型用户
                'description': '观看各类视频，时长和次数相对均衡',
                'daily_watch_time': (45, 120),  # 分钟 - 中等观看时间
                'avg_video_duration_preference': '1-3分钟',  # 偏好视频时长
                'watch_count_multiplier': 1.0,  # 观看次数倍数（基准水平）
                'interaction_rates': {
                    'like_rate': (0.04, 0.08),
                    'comment_rate': (0.01, 0.025),
                    'favorite_rate': (0.015, 0.04),
                    'repost_rate': (0.003, 0.015)
                }
            },
            'long_video_user': {
                'weight': 0.15,  # 15%长视频偏好用户
                'description': '偏好长视频（>=2分钟），观看次数少，时长长',
                'daily_watch_time': (90, 180),  # 分钟 - 长视频用户观看时间较长
                'avg_video_duration_preference': '>= 2分钟',  # 偏好视频时长
                'watch_count_multiplier': 0.4,  # 观看次数倍数（相对于平均水平）- 长视频用户观看次数显著减少
                'interaction_rates': {
                    'like_rate': (0.03, 0.06),
                    'comment_rate': (0.008, 0.02),
                    'favorite_rate': (0.01, 0.03),
                    'repost_rate': (0.002, 0.01)
                }
            }
        }
        
        # 标签偏好权重（基于性别）
        self.gender_tag_preferences = {
            '男': {
                # 基础偏好
                '搞笑': 1.3, '科技': 1.4, '游戏': 1.5, '健身': 1.2, 'FPS': 1.6, 'MOBA': 1.5,
                '颜值': 1.1, '萌宠': 0.8, '美食': 0.9, '音乐': 0.9, '美妆': 0.7, '穿搭': 0.8,
                
                # 新增标签偏好
                '沙雕': 1.4, '段子': 1.3, '神回复': 1.3, '翻车现场': 1.4, '恶搞': 1.3, '社死': 1.2, '尴尬': 1.1, '神操作': 1.3,
                '搞笑合集': 1.3, '沙雕日常': 1.4, '经典段子': 1.3, '神回复现场': 1.3, '恶搞系列': 1.3,
                '沙雕挑战': 1.4, '搞笑配音': 1.2, '段子合集': 1.3, '神评论大赏': 1.3, '翻车合集': 1.4, '恶搞实验': 1.3,
                '沙雕网友': 1.4, '段子手合集': 1.3, '恶搞挑战': 1.3, '搞笑日常': 1.3, '沙雕操作': 1.4, '神评论合集': 1.3,
                '恶搞配音': 1.2, '沙雕实验': 1.3, '搞笑萌宠': 1.2, '社死现场': 1.2, '尴尬瞬间': 1.1, '神操作': 1.3,
                
                # 影视综艺偏好
                '影视吐槽': 1.1, '综艺吐槽': 1.0, '剧情解说': 1.0, '反转神剧': 1.1, '爽剧推荐': 1.0, '爽剧解说': 1.0,
                '综艺名场面': 1.0, '剧情反转': 1.1, '爽文短剧': 1.0, '影视推荐': 1.0, '韩剧解说': 0.8, '美剧推荐': 1.1,
                '国产剧推荐': 1.0, '经典港片': 1.2, '电影解说': 1.1, '电视剧推荐': 1.0, '综艺推荐': 1.0, '真人秀': 1.0,
                '剧情': 1.0, '角色': 1.0, '演员': 1.0, '特效': 1.2, '音乐': 0.9, '画面': 1.1, '结局': 1.0, '反转': 1.1, '彩蛋': 1.0, '细节': 1.0,
                '霸总': 0.8, '甜宠': 0.7, '悬疑': 1.2, '穿越': 1.1, '高燃混剪': 1.3, 'CP混剪': 0.8, '名场面': 1.1,
                
                # 旅行户外偏好
                '旅行': 1.0, 'vlog': 0.9, '户外': 1.2, '探险': 1.3, '自驾': 1.4, '背包': 1.1, '城市': 1.0, '自然': 1.1, '风光': 1.0, '人文': 1.0, '景观': 1.0,
                '旅行vlog': 0.9, '户外探险': 1.3, '自驾游': 1.4, '背包客': 1.1, '城市探索': 1.0, '自然风光': 1.1,
                '人文景观': 1.0, '旅行攻略': 1.1, '旅行分享': 0.9, '户外运动': 1.2,
                
                # 汽车科技偏好
                '汽车': 1.6, '评测': 1.4, '知识': 1.2, '改装': 1.5, '驾驶': 1.4, '保养': 1.3, '新车': 1.4, '科技': 1.4, '产品': 1.3, '数码': 1.3, '手机': 1.2, '电脑': 1.3,
                '汽车评测': 1.5, '汽车知识': 1.4, '汽车改装': 1.5, '驾驶技巧': 1.4, '汽车保养': 1.3, '新车推荐': 1.4,
                '科技产品': 1.3, '数码评测': 1.3, '手机测评': 1.2, '电脑配置': 1.3, '科技资讯': 1.3, '数码科技': 1.3,
                
                # 教育学习偏好
                '教育': 1.0, '学习': 1.0, '考试': 0.9, '考研': 0.9, '英语': 0.9, '编程': 1.3, '技能': 1.1, '语言': 0.9, '方法': 1.0, '技巧': 1.1, '分享': 0.9,
                '英语学习': 0.9, '编程教学': 1.3, '技能学习': 1.1, '语言学习': 0.9, '学习方法': 1.0, '学习技巧': 1.0, '考试技巧': 0.9, '学习分享': 0.9,
                
                # 手工创意偏好
                '手工': 0.8, 'DIY': 0.9, '创意': 1.0, '设计': 1.0, '艺术': 0.9, '创作': 1.0, '工艺品': 0.8, '绘画': 0.8, '书法': 0.8, '摄影': 1.1, '剪辑': 1.2,
                '手工制作': 0.8, '创意DIY': 0.9, '手工教程': 0.8, '创意设计': 1.0, '艺术创作': 0.9, '手工艺品': 0.8,
                '绘画教程': 0.8, '书法教学': 0.8, '摄影技巧': 1.1, '视频剪辑': 1.2, '创意视频': 1.0, '艺术分享': 0.9,
                
                # 母婴育儿偏好（男性较低）
                '母婴': 0.6, '育儿': 0.6, '儿童': 0.7, '教育': 1.0, '亲子': 0.7, '互动': 0.8, '用品': 0.6, '技巧': 1.1, '心理': 0.9, '家庭': 1.0, '游戏': 1.2, '健康': 1.1,
                '母婴知识': 0.6, '育儿经验': 0.6, '儿童教育': 0.7, '亲子互动': 0.7, '母婴用品': 0.6, '育儿技巧': 0.6,
                '儿童心理': 0.7, '家庭教育': 1.0, '亲子游戏': 0.8, '儿童健康': 0.7, '育儿分享': 0.6, '母婴护理': 0.6,
                # 擦边相关标签偏好（男性更容易点赞转发）
                '擦边': 1.8, '性感': 1.6, '诱惑': 1.7, '美女': 1.5, '身材': 1.4, '大长腿': 1.6,
                '小蛮腰': 1.5, '马甲线': 1.3, '腹肌': 1.2, '胸肌': 1.2, '翘臀': 1.4, '美腿': 1.5,
                '锁骨': 1.3, '天鹅颈': 1.2, '蜜桃臀': 1.4, '比基尼': 1.7, '泳装': 1.6, '内衣': 1.8,
                '丝袜': 1.6, '高跟鞋': 1.3, '短裙': 1.4, '热裤': 1.5, '露脐装': 1.4, '湿身': 1.7,
                '出水芙蓉': 1.6, '撩人': 1.5, '勾魂': 1.6, '魅惑': 1.5, '风情万种': 1.4,
                # 游戏相关标签偏好（男性更容易评论收藏）
                '电竞': 1.7, '主播': 1.4, '直播': 1.3, '开黑': 1.6, '上分': 1.5, '排位': 1.5,
                '段位': 1.4, '王者': 1.6, '吃鸡': 1.5, 'LOL': 1.6, '王者荣耀': 1.5, '和平精英': 1.4,
                '原神': 1.3, '崩坏': 1.2, '明日方舟': 1.2, '阴阳师': 1.2, '操作': 1.5, '技巧': 1.4,
                '攻略': 1.6, '教学': 1.5, '解说': 1.4, '复盘': 1.3, '分析': 1.3, '战术': 1.4,
                '策略': 1.4, '装备': 1.5, '技能': 1.4, '天赋': 1.3, '符文': 1.3, '出装': 1.5,
                '铭文': 1.4, '皮肤': 1.3, '英雄': 1.4, '角色': 1.3, '团战': 1.5, '单杀': 1.4,
                '双杀': 1.4, '三杀': 1.4, '四杀': 1.4, '五杀': 1.5, '超神': 1.5, '连杀': 1.4,
                'MVP': 1.4, '翻盘': 1.5, '逆风': 1.3, '顺风': 1.3, '碾压': 1.4, '虐菜': 1.3,
                '代练': 1.2, '上分': 1.5, '掉分': 1.2, '坑货': 1.1, '队友': 1.3, '对手': 1.3,
                '敌人': 1.2, '野怪': 1.2, '小兵': 1.1, '塔': 1.2, '水晶': 1.2, '基地': 1.2, '泉水': 1.1,
                '休闲小游戏': 1.2, '挑战': 1.3,
                # 二次元标签偏好
                '二次元': 1.3, '动漫': 1.2, '番剧': 1.2, '新番': 1.2, '完结': 1.1, '追番': 1.2,
                '补番': 1.1, '推荐': 1.1, '安利': 1.1, '手办': 1.2, '周边': 1.2, '同人': 1.1,
                '本子': 1.3, '图包': 1.2, '壁纸': 1.1, '头像': 1.1, '表情包': 1.1, '声优': 1.1,
                'CV': 1.1, '配音': 1.1, '主题曲': 1.1, 'OP': 1.1, 'ED': 1.1, 'BGM': 1.1, '插曲': 1.1,
                '剧情': 1.1, '人设': 1.1, '画风': 1.1, '制作': 1.1, '经费': 1.1, '崩坏': 1.1,
                '作画': 1.1, '分镜': 1.1, '手书': 1.1, 'AMV': 1.1, 'MAD': 1.1, '高燃混剪': 1.2,
                'CP混剪': 1.1
            },
            '女': {
                # 基础偏好
                '颜值': 1.4, '萌宠': 1.3, '美食': 1.2, '音乐': 1.1, '美妆': 1.3, '穿搭': 1.2,
                '搞笑': 1.0, '科技': 0.7, '游戏': 0.8, '健身': 0.9, '宅舞': 1.2, '手势舞': 1.1,
                
                # 新增标签偏好
                '沙雕': 1.1, '段子': 1.0, '神回复': 1.0, '翻车现场': 1.1, '恶搞': 1.0, '社死': 1.0, '尴尬': 1.0, '神操作': 1.0,
                '搞笑合集': 1.0, '沙雕日常': 1.1, '经典段子': 1.0, '神回复现场': 1.0, '恶搞系列': 1.0,
                '沙雕挑战': 1.1, '搞笑配音': 1.0, '段子合集': 1.0, '神评论大赏': 1.0, '翻车合集': 1.1, '恶搞实验': 1.0,
                '沙雕网友': 1.1, '段子手合集': 1.0, '恶搞挑战': 1.0, '搞笑日常': 1.0, '沙雕操作': 1.1, '神评论合集': 1.0,
                '恶搞配音': 1.0, '沙雕实验': 1.0, '搞笑萌宠': 1.2, '社死现场': 1.0, '尴尬瞬间': 1.0, '神操作': 1.0,
                
                # 影视综艺偏好
                '影视吐槽': 1.1, '综艺吐槽': 1.2, '剧情解说': 1.1, '反转神剧': 1.2, '爽剧推荐': 1.3, '爽剧解说': 1.2,
                '综艺名场面': 1.2, '剧情反转': 1.2, '爽文短剧': 1.3, '影视推荐': 1.1, '韩剧解说': 1.4, '美剧推荐': 1.1,
                '国产剧推荐': 1.1, '经典港片': 1.0, '电影解说': 1.1, '电视剧推荐': 1.1, '综艺推荐': 1.2, '真人秀': 1.2,
                '剧情': 1.2, '角色': 1.2, '演员': 1.1, '特效': 1.0, '音乐': 1.1, '画面': 1.1, '结局': 1.2, '反转': 1.2, '彩蛋': 1.1, '细节': 1.1,
                '霸总': 1.4, '甜宠': 1.5, '悬疑': 1.1, '穿越': 1.2, '高燃混剪': 1.0, 'CP混剪': 1.3, '名场面': 1.1,
                
                # 旅行户外偏好
                '旅行': 1.2, 'vlog': 1.3, '户外': 1.0, '探险': 1.0, '自驾': 1.0, '背包': 1.0, '城市': 1.2, '自然': 1.2, '风光': 1.3, '人文': 1.2, '景观': 1.2,
                '旅行vlog': 1.3, '户外探险': 1.0, '自驾游': 1.0, '背包客': 1.0, '城市探索': 1.2, '自然风光': 1.2,
                '人文景观': 1.2, '旅行攻略': 1.1, '旅行分享': 1.2, '户外运动': 1.0,
                
                # 汽车科技偏好（女性较低）
                '汽车': 0.8, '评测': 0.9, '知识': 1.0, '改装': 0.7, '驾驶': 0.9, '保养': 0.8, '新车': 0.8, '科技': 0.8, '产品': 0.9, '数码': 0.9, '手机': 1.0, '电脑': 0.9,
                '汽车评测': 0.8, '汽车知识': 0.8, '汽车改装': 0.7, '驾驶技巧': 0.9, '汽车保养': 0.8, '新车推荐': 0.8,
                '科技产品': 0.8, '数码评测': 0.9, '手机测评': 1.0, '电脑配置': 0.9, '科技资讯': 0.8, '数码科技': 0.8,
                
                # 教育学习偏好
                '教育': 1.1, '学习': 1.1, '考试': 1.0, '考研': 1.0, '英语': 1.1, '编程': 0.9, '技能': 1.1, '语言': 1.1, '方法': 1.1, '技巧': 1.1, '分享': 1.2,
                '英语学习': 1.1, '编程教学': 0.9, '技能学习': 1.1, '语言学习': 1.1, '学习方法': 1.1, '学习技巧': 1.1, '考试技巧': 1.0, '学习分享': 1.2,
                
                # 手工创意偏好（女性较高）
                '手工': 1.3, 'DIY': 1.4, '创意': 1.2, '设计': 1.3, '艺术': 1.3, '创作': 1.2, '工艺品': 1.3, '绘画': 1.3, '书法': 1.2, '摄影': 1.2, '剪辑': 1.1,
                '手工制作': 1.3, '创意DIY': 1.4, '手工教程': 1.3, '创意设计': 1.3, '艺术创作': 1.3, '手工艺品': 1.3,
                '绘画教程': 1.3, '书法教学': 1.2, '摄影技巧': 1.2, '视频剪辑': 1.1, '创意视频': 1.2, '艺术分享': 1.3,
                
                # 母婴育儿偏好（女性较高）
                '母婴': 1.4, '育儿': 1.4, '儿童': 1.3, '教育': 1.1, '亲子': 1.4, '互动': 1.3, '用品': 1.4, '技巧': 1.1, '心理': 1.2, '家庭': 1.2, '游戏': 1.1, '健康': 1.2,
                '母婴知识': 1.4, '育儿经验': 1.4, '儿童教育': 1.3, '亲子互动': 1.4, '母婴用品': 1.4, '育儿技巧': 1.4,
                '儿童心理': 1.3, '家庭教育': 1.2, '亲子游戏': 1.3, '儿童健康': 1.3, '育儿分享': 1.4, '母婴护理': 1.4,
                # 颜值穿搭相关标签偏好（女性更容易点赞收藏）
                '写真': 1.5, '气质': 1.4, '妆造': 1.4, 'OOTD': 1.3, 'JK制服': 1.3, '汉服': 1.4,
                'cos': 1.2, '舞室练习': 1.2, '穿搭': 1.3, '时尚': 1.3, '潮流': 1.2, '搭配': 1.3,
                '风格': 1.2, '护肤': 1.4, '化妆': 1.4, '美妆': 1.3, '穿搭': 1.2, '时尚': 1.3,
                # 萌宠治愈相关标签偏好
                '萌宠': 1.3, '萌娃': 1.2, '猫': 1.4, '狗': 1.3, '仓鼠': 1.2, '异宠': 1.1,
                '可爱': 1.4, '治愈': 1.3, '解压': 1.2, '萌宠日常': 1.3, '搞笑萌宠': 1.2,
                '萌宠搞笑君': 1.1, '治愈系小仙女': 1.3, '萌宠': 1.3, '萌娃': 1.2,
                # 情感生活相关标签偏好
                '情感': 1.3, '恋爱': 1.2, '单身': 1.1, '脱单': 1.2, '分手': 1.1, '复合': 1.1,
                '前任': 1.1, '现任': 1.1, '暗恋': 1.2, '表白': 1.2, '被表白': 1.2, '拒绝': 1.1,
                '接受': 1.2, '异地恋': 1.1, '网恋': 1.1, '相亲': 1.1, '催婚': 1.1, '结婚': 1.1,
                '离婚': 1.1, '出轨': 1.1, '小三': 1.1, '渣男': 1.1, '渣女': 1.1, '绿茶': 1.1,
                '白莲花': 1.1, '家庭': 1.2, '父母': 1.2, '子女': 1.2, '婆媳': 1.1, '夫妻': 1.1,
                '情侣': 1.2, '朋友': 1.2, '闺蜜': 1.3, '兄弟': 1.1, '泪目': 1.2, '治愈': 1.3,
                '高燃': 1.1, '全程姨母笑': 1.2, '社死': 1.1, '尴尬癌': 1.1, '宿舍日常': 1.2,
                '打工日记': 1.1, '老板来了': 1.1, '熊孩子': 1.1,
                # 音乐舞蹈相关标签偏好
                '音乐': 1.1, '翻唱': 1.2, '洗脑神曲': 1.1, '舞蹈挑战': 1.3, '手势舞': 1.2,
                '宅舞': 1.2, '擦边舞蹈': 1.1, '舞室练习': 1.2, '音乐分享': 1.1, '翻唱': 1.2,
                '洗脑神曲': 1.1, '舞蹈挑战': 1.3, '手势舞': 1.2, '音乐': 1.1, '翻唱': 1.2,
                '洗脑神曲': 1.1,
                # 生活技巧相关标签偏好
                '生活': 1.2, '小技巧': 1.3, '职场': 1.1, '实用': 1.2, '教程': 1.2, '步骤': 1.2,
                '做法': 1.2, '生活小技巧': 1.3, '职场干货': 1.1, '美食': 1.2, '料理': 1.2,
                '烹饪': 1.2, '下厨': 1.2, '厨房': 1.2, '菜谱': 1.2, '探店': 1.1, '打卡': 1.1,
                '种草': 1.2, '拔草': 1.1, '推荐': 1.1, '避雷': 1.1, '踩雷': 1.1, '翻车': 1.1,
                '减肥': 1.3, '瘦身': 1.3, '健身': 0.9, '运动': 1.1, '瑜伽': 1.2, '跑步': 1.1,
                '游泳': 1.1, '骑行': 1.1
            },
            '保密': {
                # 中性偏好
                '搞笑': 1.1, '科技': 1.0, '音乐': 1.0, '萌宠': 1.0, '颜值': 1.0, '美食': 1.0,
                '健身': 1.0, '旅行': 1.0, '游戏': 1.0, '知识': 1.0, '日常': 1.0, '生活': 1.0,
                # 所有标签保持中性偏好
                '擦边': 1.0, '性感': 1.0, '诱惑': 1.0, '美女': 1.0, '帅哥': 1.0, '身材': 1.0,
                '游戏': 1.0, '电竞': 1.0, '主播': 1.0, '直播': 1.0, '二次元': 1.0, '动漫': 1.0,
                '情感': 1.0, '恋爱': 1.0, '热点': 1.0, '热搜': 1.0, '萌宠': 1.0, '音乐': 1.0,
                '影视': 1.0, '剧情': 1.0, '搞笑': 1.1, '沙雕': 1.0, '段子': 1.0, '科技': 1.0,
                '知识': 1.0, '科普': 1.0, '前沿': 1.0, '历史趣闻': 1.0, '旅行vlog': 1.0,
                '美妆教程': 1.0, '健身打卡': 1.0, '音乐分享': 1.0, '治愈系': 1.0, '高燃剪辑': 1.0,
                '沙雕实验': 1.0
            }
        }
    
    def generate_user_type(self):
        """生成用户类型"""
        types = list(self.user_types.keys())
        weights = [self.user_types[t]['weight'] for t in types]
        return np.random.choice(types, p=weights)
    
    def generate_multimodal_watch_time(self, user_type):
        """生成多峰分布的观看时间"""
        user_config = self.user_types[user_type]
        
        # 多峰分布：工作日、周末、节假日有不同的观看模式
        # 工作日：晚上7-11点是高峰
        # 周末：下午2-6点和晚上8-11点是高峰
        # 节假日：全天相对均匀，但下午和晚上稍高
        
        # 生成每日观看时间（分钟）
        daily_watch_time = np.random.uniform(*user_config['daily_watch_time'])
        
        # 模拟一天内的观看时间分布（24小时）
        hour_weights = self._get_hour_weights()
        
        # 生成观看时间分布
        watch_sessions = []
        remaining_time = daily_watch_time
        
        # 生成2-5个观看时段
        num_sessions = np.random.randint(2, 6)
        
        for _ in range(num_sessions):
            if remaining_time <= 0:
                break
                
            # 选择观看时段
            hour = np.random.choice(range(24), p=hour_weights)
            
            # 生成该时段的观看时长（5-60分钟）
            session_duration = min(
                np.random.exponential(20),  # 指数分布，平均20分钟
                remaining_time,
                60  # 单次最多60分钟
            )
            session_duration = max(5, session_duration)  # 最少5分钟
            
            watch_sessions.append({
                'hour': int(hour),
                'duration_minutes': round(float(session_duration), 2)
            })
            
            remaining_time -= session_duration
        
        return daily_watch_time, watch_sessions
    
    def _get_hour_weights(self):
        """获取24小时的观看权重（多峰分布）"""
        # 工作日模式：晚上7-11点高峰
        weekday_weights = [0.02] * 6 + [0.05] * 2 + [0.08] * 4 + [0.12] * 2 + [0.15] * 4 + [0.08] * 2 + [0.05] * 4
        
        # 周末模式：下午2-6点和晚上8-11点高峰
        weekend_weights = [0.03] * 6 + [0.08] * 2 + [0.12] * 4 + [0.15] * 2 + [0.10] * 2 + [0.15] * 3 + [0.08] * 5
        
        # 随机选择模式（70%工作日，30%周末）
        if np.random.random() < 0.7:
            weights = weekday_weights
        else:
            weights = weekend_weights
        
        # 归一化权重
        total_weight = sum(weights)
        return [w / total_weight for w in weights]

    def get_user_type_tag_adjustments(self, user_type):
        """根据用户类型返回标签权重调整"""
        # 基础权重调整
        base_adjustments = {
            'short_video_user': {
                # 短视频用户偏好：娱乐性强、热门、潮流内容
                '搞笑': 1.5, '沙雕': 1.6, '段子': 1.4, '神回复': 1.5, '翻车现场': 1.4,
                '沙雕日常': 1.5, '段子合集': 1.4, '神回复现场': 1.4, '恶搞系列': 1.3,
                '热门': 1.4, '潮流': 1.4, '颜值': 1.3, '美女': 1.3, '帅哥': 1.3,
                '舞蹈': 1.4, '音乐': 1.3, '挑战': 1.4, '游戏': 1.3, '萌宠': 1.2,
                # 减少深度内容偏好
                '教育': 0.7, '科普': 0.8, '纪录片': 0.6, '专业知识': 0.7, '深度分析': 0.6
            },
            'long_video_user': {
                # 长视频用户偏好：专业性强、深度内容、教育类
                '教育': 1.6, '科普': 1.5, '纪录片': 1.7, '专业知识': 1.5, '深度分析': 1.6,
                '历史': 1.4, '科学': 1.5, '文化': 1.4, '哲学': 1.3, '艺术': 1.4,
                '教程': 1.5, '教学': 1.4, '讲解': 1.5, '分析': 1.4, '研究': 1.3,
                '访谈': 1.4, '演讲': 1.5, '辩论': 1.3, '会议': 1.2, '研讨会': 1.3,
                # 减少娱乐内容偏好
                '搞笑': 0.6, '沙雕': 0.5, '段子': 0.7, '热门': 0.8, '潮流': 0.7
            },
            'mixed_user': {
                # 混合型用户：均衡偏好，所有标签权重相对均衡
                '教育': 1.1, '科普': 1.1, '搞笑': 1.1, '热门': 1.1, '潮流': 1.1,
                '专业知识': 1.1, '娱乐': 1.1, '生活': 1.1, '情感': 1.1, '音乐': 1.1
            }
        }

        return base_adjustments.get(user_type, {})

    def generate_favorite_tags(self, gender, user_type, age_group):
        """生成用户喜爱的标签"""
        # 基础标签权重
        base_weights = {tag: 1.0 for tag in self.tag_pool}

        # 根据性别调整权重
        gender_prefs = self.gender_tag_preferences.get(gender, {})
        for tag in base_weights:
            multiplier = gender_prefs.get(tag, 1.0)
            base_weights[tag] *= multiplier

        # 根据年龄段调整权重
        age_adjustments = self.get_age_adjustments(age_group)
        for tag in base_weights:
            multiplier = age_adjustments.get(tag, 1.0)
            base_weights[tag] *= multiplier

        # 根据用户类型调整标签权重（与观看行为模式关联）
        user_type_adjustments = self.get_user_type_tag_adjustments(user_type)
        for tag in base_weights:
            multiplier = user_type_adjustments.get(tag, 1.0)
            base_weights[tag] *= multiplier
        
        # 根据用户类型调整标签数量（基于观看行为模式）
        if user_type == 'short_video_user':
            num_tags = np.random.randint(8, 15)  # 短视频用户兴趣广泛，标签较多
        elif user_type == 'long_video_user':
            num_tags = np.random.randint(3, 8)   # 长视频用户兴趣专注，标签较少
        else:  # mixed_user
            num_tags = np.random.randint(5, 10)  # 混合型用户标签适中
        
        # 根据权重选择标签
        tags = list(base_weights.keys())
        weights = list(base_weights.values())
        weights = np.array(weights) / sum(weights)  # 归一化
        
        selected_tags = np.random.choice(tags, size=num_tags, replace=False, p=weights)
        return list(selected_tags)
    
    
    def generate_user_data(self):
        """生成用户数据"""
        users = []
        
        for i in range(1, self.num_users + 1):
            # 基本信息
            user_id = f'U{i:05d}'
            register_date = self.start_date + timedelta(
                days=random.randint(0, (self.end_date - self.start_date).days)
            )
            gender = random.choice(['男', '女', '保密'])

            # 生成年龄段
            age_group = self.generate_age_group()

            # 根据年龄段生成具体年龄
            age = self.generate_age_from_group(age_group)

            # 判断是否为假期时间段（基于注册时间）
            is_holiday_period = self.is_holiday_period(register_date)
            
            # 用户类型
            user_type = self.generate_user_type()
            
            # 生成多峰分布的观看时间
            daily_watch_time, watch_sessions = self.generate_multimodal_watch_time(user_type)
            
            # 生成喜爱标签
            favorite_tags = self.generate_favorite_tags(gender, user_type, age_group)
            
            # 计算总观看次数（基于观看时间和用户类型偏好估算）
            avg_video_duration = 45  # 平均视频时长（秒）
            # 根据用户类型调整观看次数倍数
            watch_count_multiplier = self.user_types[user_type]['watch_count_multiplier']
            base_watch_count = daily_watch_time * 60 / avg_video_duration
            total_watch_count = int(base_watch_count * watch_count_multiplier)
            
            user_data = {
                # user_id：用户在系统中的唯一身份标识
                # 技术细节：通常由平台在注册或首次访问时生成，保证全局唯一，可用于后续跨表关联、行为追踪、画像构建等
                'user_id': user_id,
                
                # register_time：用户账号的首次创建时间
                # 技术细节：精确到天（或秒）的时间戳，可用于计算用户生命周期、留存率、按注册批次做 A/B Test 等
                'register_time': register_date.strftime('%Y-%m-%d'),
                
                # gender：用户自填或系统推断的性别
                # 技术细节：多为枚举值（男 / 女 / 保密），可用于性别维度的人群分析、推荐策略差异、广告投放定向等
                'gender': gender,
                
                # avg_watch_minutes：用户"平均每日观看视频的总时长"（单位：分钟）
                # 技术细节：
                #   - 计算口径通常是 ∑(每次播放时长) ÷ 统计天数
                #   - 是衡量用户粘性和内容消费深度的核心指标，可用于活跃分层（轻度/中度/重度）、预测付费意愿、推荐权重调整等
                'avg_watch_minutes': round(daily_watch_time, 2),  # 分钟单位
                
                # total_watch_count：用户累计观看视频的"总次数"
                # 技术细节：
                #   - 只要一次播放事件被记录（无论是否看完），计数加 1
                #   - 与 avg_watch_minutes 结合可计算"平均每次观看时长"，进而判断用户偏好短视频还是长视频
                'total_watch_count': total_watch_count,
                
                # favorite_tags：用户"喜欢/偏好"的视频标签列表
                # 技术细节：
                #   - 一般来源于用户主动点赞、收藏、正向互动或算法模型推断的 top-N 标签
                #   - 用于构建兴趣画像，实现个性化推荐、内容冷启动、广告匹配、Push 文案定制等
                'favorite_tags': json.dumps(favorite_tags, ensure_ascii=False)
            }
            
            users.append(user_data)
        
        return pd.DataFrame(users)

    def generate_age_group(self):
        """生成年龄段"""
        # 年龄段分布（基于中国短视频用户统计）
        age_groups = {
            '18-24': 0.35,  # 年轻人
            '25-34': 0.45,  # 青年人
            '35-44': 0.15,  # 中年人
            '45+': 0.05     # 中老年人
        }

        return random.choices(
            list(age_groups.keys()),
            weights=list(age_groups.values()),
            k=1
        )[0]

    def is_holiday_period(self, date):
        """判断是否为假期时间段"""
        month = date.month
        day = date.day

        # 春节假期 (1月下旬-2月上旬)
        if (month == 1 and day >= 20) or (month == 2 and day <= 10):
            return True

        # 清明假期 (4月上旬)
        if month == 4 and 4 <= day <= 6:
            return True

        # 五一假期 (5月上旬)
        if month == 5 and 1 <= day <= 5:
            return True

        # 端午假期 (5月下旬-6月上旬)
        if (month == 5 and day >= 25) or (month == 6 and day <= 5):
            return True

        # 中秋假期 (9月中旬)
        if month == 9 and 10 <= day <= 15:
            return True

        # 国庆假期 (10月上旬)
        if month == 10 and 1 <= day <= 7:
            return True

        # 暑假 (7月-8月)
        if month in [7, 8]:
            return True

        # 寒假 (12月下旬-1月上旬)
        if (month == 12 and day >= 20) or (month == 1 and day <= 15):
            return True

        return False

    def get_age_adjustments(self, age_group):
        """根据年龄段调整标签偏好权重"""
        adjustments = {}

        if age_group == '18-24':  # 年轻人
            adjustments.update({
                '游戏': 1.6, '电竞': 1.8, 'FPS': 1.7, 'MOBA': 1.7, '王者荣耀': 1.9,
                '二次元': 1.5, '动漫': 1.4, '音乐': 1.3, '宅舞': 1.4, '手势舞': 1.3,
                '颜值': 1.2, '美妆': 1.3, '穿搭': 1.2, '擦边': 1.4, '美女': 1.3,
                '搞笑': 1.2, '沙雕': 1.3, '萌宠': 1.1, '美食': 1.1, '科技': 1.2
            })

        elif age_group == '25-34':  # 青年人
            adjustments.update({
                '职场': 1.4, '生活小技巧': 1.3, '知识': 1.3, '科普': 1.2, '旅行': 1.3,
                '美食': 1.2, '美妆': 1.2, '穿搭': 1.2, '健身': 1.3, '音乐': 1.2,
                '情感': 1.4, '恋爱': 1.3, '家庭': 1.2, '萌宠': 1.1, '搞笑': 1.1,
                '游戏': 1.2, '科技': 1.3, '动漫': 1.1
            })

        elif age_group == '35-44':  # 中年人
            adjustments.update({
                '职场': 1.6, '生活小技巧': 1.5, '知识': 1.4, '科普': 1.3, '美食': 1.3,
                '家庭': 1.5, '父母': 1.4, '子女': 1.3, '情感': 1.4, '养生': 1.3,
                '旅行': 1.4, '历史': 1.2, '新闻': 1.2, '健身': 1.2, '音乐': 1.1
            })

        else:  # 45+
            adjustments.update({
                '养生': 1.5, '健康': 1.4, '美食': 1.3, '旅行': 1.4, '历史': 1.3,
                '家庭': 1.6, '孙子': 1.4, '养生': 1.5, '广场舞': 1.3, '戏曲': 1.2,
                '新闻': 1.3, '养生': 1.5, '钓鱼': 1.2, '书法': 1.1, '太极': 1.2
            })

        return adjustments

    def generate_age_from_group(self, age_group):
        """根据年龄段生成具体年龄"""
        if age_group == '18-24':
            return random.randint(18, 24)
        elif age_group == '25-34':
            return random.randint(25, 34)
        elif age_group == '35-44':
            return random.randint(35, 44)
        else:  # 45+
            return random.randint(45, 65)

def main():
    """主函数"""
    import sys
    
    # 从命令行参数获取用户数量
    num_users = 1000
    if len(sys.argv) > 1:
        try:
            num_users = int(sys.argv[1])
        except ValueError:
            print("用户数量必须是整数，使用默认值1000")
    
    print(f"开始生成 {num_users} 个用户的增强数据...")
    
    # 创建生成器
    generator = EnhancedUserGenerator(num_users=num_users)
    
    # 生成数据
    df = generator.generate_user_data()
    
    # 保存到CSV
    import os
    output_file = 'short-video-recommandation-algorithms-master/data/users_1000_20250907.csv'
    os.makedirs(os.path.dirname(output_file), exist_ok=True)
    df.to_csv(output_file, index=False, encoding='utf-8-sig')
    
    print(f"用户数据已保存到: {output_file}")
    print(f"生成了 {len(df)} 个用户")
    print("\n数据预览:")
    print(df[['user_id', 'register_time', 'gender', 'avg_watch_minutes', 'total_watch_count', 'favorite_tags']].head(10))
    
    # 统计信息
    print(f"\n统计信息:")
    print(f"平均观看时长: {df['avg_watch_minutes'].mean():.2f} 分钟")
    print(f"平均观看次数: {df['total_watch_count'].mean():.2f}")
    
    # 性别分布
    print(f"\n性别分布:")
    print(df['gender'].value_counts())
    
    # 注册时间分布（按年份）
    df['register_year'] = pd.to_datetime(df['register_time']).dt.year
    print(f"\n注册年份分布:")
    print(df['register_year'].value_counts().sort_index())

if __name__ == "__main__":
    main()
